home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-04-27 | 2.6 KB | 68 lines | [TEXT/????] |
- ;;; The following procedure attempts to improve on the precision of the
- ;;; roots returned by POLY->ROOTS, and will adequately find multiple
- ;;; roots as well. (POLY->ROOTS appears to split these multiple roots
- ;;; by perturbations on the order or (sqrt *machine-epsilon*); in some
- ;;; contexts this splitting may be a desirable feature.) It does this
- ;;; by computing the first two derivatives yp and ypp of the given
- ;;; polynomial y, and using a single newton-iteration on the function
- ;;; u = y/yp (which is why ypp is required). We use u instead of y
- ;;; because it handles the problem of multiple roots: such a root of y
- ;;; becomes a single root of u. This is essential because only a single
- ;;; newton-iteration is to be used.
-
- (define (new-improved-poly->roots y . initial-guess)
- (let* ((fuzzy-roots (apply poly->roots (cons y initial-guess)))
- (yp (deriv-poly y))
- (ypp (deriv-poly yp)))
- (define (newton x)
- (let* ((yx (poly-value y x))
- (ypx (poly-value yp x))
- (yppx (poly-value ypp x))
- (ux (/ yx ypx))
- (upx (- 1 (* yx yppx (/ 1 ypx ypx)))))
- (- x (/ ux upx))))
- (map-n newton *fuzzy-repeat-count* fuzzy-roots)))
-
- (define (new-improved-poly->roots y . initial-guess)
- (let* ((fuzzy-roots (apply poly->roots (cons y initial-guess)))
- (yp (deriv-poly y))
- (ypp (deriv-poly yp)))
- (define (newton x)
- (let* ((yx (poly-value y x))
- (ypx (poly-value yp x))
- (yppx (poly-value ypp x))
- (ux (/ yx ypx))
- (upx (- 1 (* yx yppx (/ 1 ypx ypx)))))
- (- x (/ ux upx))))
- (map-n newton *fuzzy-repeat-count* fuzzy-roots)))
-
- (define (nu-poly->roots y . initial-guess)
- (let* ((fuzzy-roots (apply poly->roots (cons y initial-guess)))
- (yp (deriv-poly y))
- (ypp (deriv-poly yp))
- (num (mul-polys y yp))
- (den (sub-polys (mul-polys yp yp) (mul-polys y ypp)))
- (qr (div-polys num den))
- (q (car qr))
- (r (cadr qr)))
- (define (newton x)
- (- x (+ (poly-value q x)
- (/ (poly-value r x) (poly-value den x)))))
- (map-n newton *fuzzy-repeat-count* fuzzy-roots)))
-
- (define *fuzzy-repeat-count* 1)
-
- (define (improved-poly->roots y . initial-guess)
- (let* ((fuzzy-roots (apply poly->roots (cons y initial-guess)))
- (yp (deriv-poly y)))
- (define (newton x)
- (let ((yx (poly-value y x))
- (ypx (poly-value yp x)))
- (- x (/ yx ypx))))
- (map-n newton *fuzzy-repeat-count* fuzzy-roots)))
-
- (define (map-n f n list)
- (if (zero? n)
- list
- (map-n f (- n 1) (map f list))))
-